<?php

namespace App\Task;

use App\Websocket\ImWebsocket;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Redis\Redis;
use Hyperf\WebSocketServer\Sender;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use RedisException;

class ClearExpireChatLinkTask extends AbstractBaseTask
{
    protected Redis $redis;
    #[Inject]
    protected Sender $sender;

    public function execute(): void
    {
        $expireTime = time() - ImWebsocket::HEARTBEAT_INTERVAL * 3;
        $succ = 0;
        try {
            $this->redis = $this->container->get(Redis::class);
            $fds = $this->redis->zRangeByScore(ImWebsocket::KeyFds(), '0', strval($expireTime));
            if (empty($fds)) {
                return;
            }
            foreach ($fds as $fd) {
                $info = $this->redis->hGetAll(ImWebsocket::KeyFd($fd));
                if (!empty($info['groupId'])) {
                    $this->redis->sRem(ImWebsocket::KeyGroup($info['groupId']), (int)$fd);
                }
                $this->redis->zRem(ImWebsocket::KeyFds(), (int)$fd);
                $this->redis->del(ImWebsocket::KeyFd($fd));
                $this->sender->disconnect((int)$fd);
                $succ++;
            }
            if ($succ) {
                $this->logger->warning(sprintf('清理异常连接 %d 个', $succ));
            }
        } catch (NotFoundExceptionInterface|ContainerExceptionInterface|RedisException $e) {
            $this->logger->error('redis连接获取失败');
            return;
        }
    }
}